//C- -------------------------------------------------------------------
//C- Java DjVu (r) (v. 0.8)
//C- Copyright (c) 2004-2005 LizardTech, Inc.  All Rights Reserved.
//C- Java DjVu is protected by U.S. Pat. No.C- 6,058,214 and patents
//C- pending.
//C-
//C- This software is subject to, and may be distributed under, the
//C- GNU General Public License, Version 2. The license should have
//C- accompanied the software or you may obtain a copy of the license
//C- from the Free Software Foundation at http://www.fsf.org .
//C-
//C- The computer code originally released by LizardTech under this
//C- license and unmodified by other parties is deemed "the LIZARDTECH
//C- ORIGINAL CODE."  Subject to any third party intellectual property
//C- claims, LizardTech grants recipient a worldwide, royalty-free,
//C- non-exclusive license to make, use, sell, or otherwise dispose of
//C- the LIZARDTECH ORIGINAL CODE or of programs derived from the
//C- LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
//C- General Public License.   This grant only confers the right to
//C- infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
//C- the extent such infringement is reasonably necessary to enable
//C- recipient to make, have made, practice, sell, or otherwise dispose
//C- of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
//C- any greater extent that may be necessary to utilize further
//C- modifications or combinations.
//C-
//C- The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
//C- OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//C- TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
//C- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//C-
//C- In addition, as a special exception, LizardTech Inc. gives permission
//C- to link the code of this program with the proprietary Java
//C- implementation provided by Sun (or other vendors as well), and
//C- distribute linked combinations including the two. You must obey the
//C- GNU General Public License in all respects for all of the code used
//C- other than the proprietary Java implementation. If you modify this
//C- file, you may extend this exception to your version of the file, but
//C- you are not obligated to do so. If you do not wish to do so, delete
//C- this exception statement from your version.
//C- -------------------------------------------------------------------
//C- Developed by Bill C. Riemers, Foxtrot Technologies Inc. as work for
//C- hire under US copyright laws.
//C- -------------------------------------------------------------------
//
package com.lizardtech.djvu{
import flash.utils.getDefinitionByName;

import java.io.*;
import java.util.*;


/**
 * This is a basic implimentation of the DjVuInterface.  Children should have
 * a static method for creating an instance of the class using the
 * referenced object to initialize DjVuObjects storage.
 *
 * @author Bill C. Riemers
 * @version $Revision: 1.11 $
 */
public class DjVuObject
  implements DjVuInterface
{
  //~ Static fields/initializers ---------------------------------------------

  
  //This flag indicates if references are available.
  public static var hasReferences:Boolean = false;

  /*
  // This constructor will be used to create soft references.
  private static final var newSoftReference:Constructor;
  
  /// This constructor will be used to create weak references.
  private static final var newWeakReference:Constructor;
  
  //This method will be used to read references
  private static final var getMethod:Method;	

  static
  {
    var xgetMethod:Method=null;
    var xnewSoftReference:Constructor=null;
    var xnewWeakReference:Constructor=null;
    try
    {
      xgetMethod =
        Class.forName("java.lang.ref.Reference").getMethod("get", null);
      final var params:Array= {Object.class};
      xnewWeakReference=xnewSoftReference =
        Class.forName("java.lang.ref.SoftReference").getConstructor(params);
      xnewWeakReference =
        Class.forName("java.lang.ref.WeakReference").getConstructor(params);
    }
    catch(final var ignored:Throwable) {}
    getMethod=xgetMethod;
    newSoftReference=xnewSoftReference;
    newWeakReference=xnewWeakReference;
    hasReferences = (newSoftReference != null);
  }
  */

  //~ Instance fields --------------------------------------------------------

  private var djvuOptions:DjVuOptions= null;

  //~ Methods ----------------------------------------------------------------

  public static function printStackTrace(exp:*):void{
    //exp.printStackTrace(DjVuOptions.err);
    trace("error: " + exp);
    trace(exp.getStackTrace());
  }
  
  public static function verbose(message:String):void{
    trace(message);    
  }
  
  public static function logError(message:String):void{
    trace(message);    
  }
  
  /**
   * Set the DjVuOptions to be used by this object.
   *
   * @param options DjVuOptions to use.
   */
  public final function setDjVuOptions(options:DjVuOptions):void{
    djvuOptions = options;
  }

  /**
   * Query the DjVuOptions used by this object.
   *
   * @return DjVuOptions in use
   */
  public function getDjVuOptions():DjVuOptions{
    var retval:DjVuOptions= djvuOptions;

    if(retval == null)
    {
      djvuOptions = retval = new DjVuOptions();
    }

    return retval;
  }

  /**
   * Retrieve the value from a reference.  If the specified object is not a reference then
   * that value will be returned.
   *
   * @param value The reference to query.
   *
   * @return The value contained by the reference.
   */
  public static function getFromReference(value:Object):Object{
    return (hasReferences &&(value != null))?invoke(null, value, null):value;
  }

  /**
   * Creates the desired class.  bestClass is not null, it will be created.
   * Otherwise the named class will be created.  If the creation fails, a
   * null will be returned.
   *
   * @param options the DjVuOptions instance the new object should use.
   * @param bestClass The class we wish to create.
   * @param className The name of the class to create as default.
   *
   * @return the newly created object
   */
  public static function create(
    options:DjVuOptions,
    bestClass:Class,
    className:*):DjVuInterface{

	if(className is String) { 

	    var defaultClass:Class= null;
	
	
	    if(bestClass == null) {
	      try
	      {
	        defaultClass = flash.utils.getDefinitionByName(className) as Class;
	      }
	      catch(exp:*)
	      {
	      	trace("class creation fail: " + className);
	      	trace(exp.getStackTrace());
	        return null;
	      }
	    }
	
	    return create(options, bestClass, defaultClass);
	} else if (className is Class) {
	
		var retval:DjVuInterface= null;
	    try
	    {
	      if(bestClass != null)
	      {
	        try
	        {
	           retval = new bestClass() as DjVuInterface;  //DjVuInterface(bestClass.newInstance());
	        }
	        catch(exp:*)        
	        {
	           retval = new defaultClass() as DjVuInterface; //DjVuInterface(defaultClass.newInstance());
	        }
	      }
	      else if(className != null)
	      {
	          retval = new className() as DjVuInterface; // retval = DjVuInterface(defaultClass.newInstance());
	      }
	      retval.setDjVuOptions(options);
	    }
	    catch(exp:*)
	    {
	      exp.printStackTrace(); //DjVuOptions.err);
	      
	    }
	    
	
	    return retval;	
	}
	
	return null;
  }

  
  /**
   * Create a new SoftReference, if supported.
   *
   * @param value The value to wrap in a soft reference.
   * @param defaultValue The value to return if soft references are not
   *        supported.
   *
   * @return The soft reference, or default value.
   */
  public static function createSoftReference(
    value:Object,
    defaultValue:Object):Object{
    
    return defaultValue;
  }

  /**
   * Create a new WeakReference, if supported.
   *
   * @param value The value to wrap in a weak reference.
   * @param defaultValue The value to return if weak references are not
   *        supported.
   *
   * @return The weak reference, or default value.
   */
  public static function createWeakReference(
    value:Object,
    defaultValue:Object):Object{

    return defaultValue;
  }
  
  /**
   * This is a wrapper for method.invoke that catches and reports exceptions.
   *
   * @param method class method to invoke
   * @param o the object to invoke the method on
   * @param args the arguments to send to the method
   *
   * @return the method.invoke return value or null
   */
  public static function invoke(method:*, o:Object, args:Array):Object{
    var retval:Object=null;
    try
    {
      retval=method.invoke(o,args);
    }
    catch(exp:*) 
    {
      exp.printStackTrace();//(DjVuOptions.err);
    }
    return retval;
  }
  
  public static function checkLockTime(lockTime:Number, maxTime:Number):void{
  	var currentTime:Date = new Date();
    var t:Number=currentTime.getMinutes()*60000+currentTime.getSeconds()*1000+currentTime.getMilliseconds() -lockTime;
    if(t > maxTime)
    {
        try { 
            throw new Error("lock held for "+t+" ms"); 
        } catch(exp:*) {
            exp.printStackTrace();//(DjVuOptions.err);
        }
    }
  }
  
  public function clone():Object {
  	return java.util.cloner.clone(this);
  }
}}